package mud.player;

import mud.Exit;
import mud.Interactable;
import mud.Room;
import mud.events.Event;
import mud.unit.Character;
import terminal.Terminal;
import terminal.TerminalColor;

/** A character that is remotely controlled by a human via a terminal */
public class PlayerCharacter extends Character {

    /** the remote client terminal */
    private final Terminal terminal;
    
    /** the remote player */
    private final Player player;
    
    /**
     * Constructor
     * @param player the remote player
     * @param terminal the remote client terminal
     */
    public PlayerCharacter(Player player, Terminal terminal) {
        this.terminal = terminal;
        this.player = player;
    }

    @Override
    public void observe(Event event) {
        player.observe(event);
    }

    @Override
    public void look(Interactable target) {
        super.look(target);

        if (target instanceof Room) {
            terminal.println(TerminalColor.GREEN, target.getName());
        }
        
        String appearance = target.getAppearance();
        if (appearance != null) {
            terminal.println(appearance);
        } else {
            terminal.println(
                "There is nothing particularly noteworthy about "
                + player.getIdentifier(target) + ".");
        }

        if (target instanceof Room) {
            for (Interactable occupant : ((Room) target).getOccupants()) {
                if (!occupant.equals(this)) {
                    terminal.println(
                        player.getIdentifier(occupant) + " is here.");
                }
            }
        }
    }

    /**
     * @return the remote client terminal
     */
    public Terminal getTerminal() {
        return terminal;
    }

    /**
     * Attempts to return the user-specified target of an action
     * @param input the string containing a possible target identifier
     * @return the corresponding target, or null
     */
    public Interactable parseTarget(String input) {
        Interactable target = null;
        for (Interactable occupant : getRoom().getOccupants()) {
            if (occupant.getName().equalsIgnoreCase(input)) {
                target = occupant;
                break;
            }
        }
        return target;
    }

    /**
     * Attempts to return the user-specified exit
     * @param input the string containing a possible exit identifier
     * @return the corresponding exit, or null
     */
    public Exit parseExit(String input) {
        for (Exit exit : getRoom().getExits()) {
            if (exit.getName().equalsIgnoreCase(input)) {
                return exit;
            }
        }
        return null;
    }

    /**
     * Returns true if the character is identified by the given string
     * @param identifier the identifier in question
     * @return whether <code>identifier</code> identifies the character
     */
    public boolean isIdentifiedBy(String identifier) {
        return getName().equalsIgnoreCase(identifier);
    }
}
